/*
File:		LaserSword.cpp
Author:		Ben Feldmann
Purpose:	Class for managing the laser sword weapon
*/

#include "LaserSword.h"
#include "EventSystem.h"
#include "GamePlayState.h"
#include "ObjectManager.h"
#include "SGD Wrappers/CSGD_TextureManager.h"
#include "SGD Wrappers/CSGD_Direct3D.h"
#include "SGD Wrappers/CSGD_XAudio2.h"
#include "Animation.h"

LaserSword::LaserSword(Player* owner)
{
	isAttacking		= false;
	isSpcAttacking	= false;
	spcAttacked		= false;
	atkTimer		= 0.0f;
	spcAtkTimer		= 0.0f;
	spcAtkCoolTimer = 0.0f;
	atkRotation		= 0.0f;
	rotation		= 0.0f;

	prevMoveSpeed		= 0.0f;
	prevAtkSpeed		= 0.0f;
	prevAnimationSpeed	= 0.0f;
	curAtkSpeed			= 0.0f;
	curMoveSpeed		= 0.0f;
	curAnimationSpeed	= 0.0f;
	berserker			= false;
	berserkState		= 0;
	berserkTimer		= 0.0f;
	berserkDuration		= 0.0f;

	//SetTextureID(CSGD_TextureManager::GetInstance()->LoadTexture(_T("Graphics/Dummy Images/laserSword.png")));

	SetDamage(35.0f);
	SetSpcDamage(100.0f);
	SetCoolTimer(15.0f);	// TEST, CHANGE LATER
	SetCoolSeconds(15.0f);
	SetAtkSpeed(.5f);
	SetEnergyCost(20.0f);
	SetMetalPrice(50);
	SetCircuitPrice(100);
	SetOwner(owner);

	SetX(GetOwner()->GetX() + (GetOwner()->GetWidth()/2.0f));
	SetY(GetOwner()->GetY() + (GetOwner()->GetHeight()/2.0f));
	SetHeight(16);
	SetWidth(128);
	type = OBJ_WEAPON;

	meleeType = MW_SWORD;
	type = OBJ_WEAPON;

	SetDirection(owner->GetDirection());

	oneFrame = false;

	ObjectManager::GetInstance()->AddObject(this);
	Release();

	//swordAttack1 = CSGD_XAudio2::GetInstance()->SFXLoadSound(_T("Sound/Melee Weapons/swordAttack1.wav"));
	//swordAttack2 = CSGD_XAudio2::GetInstance()->SFXLoadSound(_T("Sound/Melee Weapons/swordAttack2.wav"));
}

LaserSword::~LaserSword()
{
	ObjectManager::GetInstance()->RemoveObject(this);
}

bool LaserSword::CheckCollision(IEntity* base) 
{
	if(Entity::CheckCollision(base) == true && base != this->GetOwner() && base->GetType() != OBJ_PICKUP && base->GetType() != OBJ_WEAPON)
	{
		if(GetOwner()->GetClock() == false && (base->GetType() == OBJ_ENEMY || base->GetType() == OBJ_HAZARD))
		{
			if(isAttacking == true && oneFrame == true)
			{
				EventSystem::GetInstance()->SendEvent("target_hit", base, new float(GetDamage() + berserkState));
				oneFrame = false;

				Berserk();

				return true;
			}
			else if(isSpcAttacking == true && oneFrame == true)
			{
				EventSystem::GetInstance()->SendEvent("target_hit", base, new float(GetSpcDamage() + berserkState*2));
				oneFrame = false;

				Berserk();

				return true;
			}
			else
				return false;
		}
		else if (GetOwner()->GetClock() == true && (base->GetType() == OBJ_ENEMY || base->GetType() == OBJ_HAZARD))
		{
			if(isAttacking == true && oneFrame == true)
			{
				EventSystem::GetInstance()->SendEvent("target_hit", base, new float((GetDamage() + berserkState)*1.5f));
				oneFrame = false;

				Berserk();

				return true;
			}
			else if(isSpcAttacking == true && oneFrame == true)
			{
				EventSystem::GetInstance()->SendEvent("target_hit", base, new float((GetSpcDamage() + berserkState*2)*1.5f));
				oneFrame = false;

				Berserk();

				return true;
			}
			else
				return false;
		}
	}
	return false;
}

void LaserSword::Attack() 
{
	if(isAttacking == false)
	{
		weaponAnimation[GetDirection()].Play();
		atkRotation = rotation;
		isAttacking = true;
		oneFrame = true;
	}
}

void LaserSword::SpecialAttack() 
{
	if(isSpcAttacking == false && spcAttacked == false)
	{
		specialAnimation.Play();
		atkRotation = rotation;
		isSpcAttacking = true;
		spcAttacked = true;

		oneFrame = true;

		GetOwner()->SetEnergy(GetOwner()->GetEnergy() - GetEnergyCost());

		SetCoolTimer(0.0f);
	}
}

void LaserSword::Update(float elapsed)
{
	if(berserker)
	{
		berserkTimer += elapsed;

		if(berserkTimer >= berserkDuration)
		{
			berserker = false;
			berserkTimer = 0;
			berserkState = 0;
			berserkDuration = 0;
			curMoveSpeed = prevMoveSpeed;
			curAtkSpeed = prevAtkSpeed;
			curAnimationSpeed	= prevAnimationSpeed;

			SetAtkSpeed(prevAtkSpeed);
			GetOwner()->SetMoveSpeed(prevMoveSpeed);
			for(int i = 0; i < 4; ++i)
			{
				weaponAnimation[i].SetPlaySpeed(prevAnimationSpeed);
			}
		}
	}


	SetDirection(GetOwner()->GetDirection());
	if(isSpcAttacking == true)
	{
		GetOwner()->SetAnimation(&specialAnimation);
	}
	else if(GetOwner()->GetAnimation() != &weaponAnimation[GetDirection()])
	{
		GetOwner()->SetAnimation(&weaponAnimation[GetDirection()]);
	}

	if(isAttacking == true)
	{
		atkTimer += elapsed;

		if(atkTimer >= GetAtkSpeed())
		{
			isAttacking = false;
			atkRotation = rotation;
			atkTimer = 0.0f;
		}
	}
	if(spcAttacked == true)
	{
		if(isSpcAttacking == true)
			spcAtkTimer += elapsed;
		else
			SetCoolTimer(GetCoolTimer() + elapsed);

		if(spcAtkTimer >= 1.0f)
		{
			specialAnimation.Stop();
			isSpcAttacking = false;
			spcAtkTimer = 0.0f;
		}

		if(GetCoolTimer() >= GetCoolSeconds())
		{
			spcAttacked = false;
		}
	}
}

void LaserSword::Render()
{
	
}

void LaserSword::Berserk()
{
	berserkTimer = 0;

	if(berserkState == 0)
	{
		berserker			= true;
		berserkDuration		= 3.0f;
		prevMoveSpeed		= GetOwner()->GetMoveSpeed();
		curMoveSpeed		= prevMoveSpeed;
		prevAtkSpeed		= GetAtkSpeed();
		curAtkSpeed			= prevAtkSpeed;
		prevAnimationSpeed  = weaponAnimation[0].GetPlaySpeed();
		curAnimationSpeed	= prevAnimationSpeed;
	}

	if(berserkState <= 5)
	{
		++berserkState;
		curMoveSpeed += 10;
		curAtkSpeed -= 0.05f;
		curAnimationSpeed += 0.35f;

		SetAtkSpeed(curAtkSpeed);
		GetOwner()->SetMoveSpeed(curMoveSpeed);

		for(int i = 0; i < 4; ++i)
		{
			weaponAnimation[i].SetPlaySpeed(curAnimationSpeed);
		}
	}
}

RECT LaserSword::GetRect()
{
	RECT rect = {};

	int dir = GetDirection();

	switch(dir)
	{
	case 0:
		{
			rect = MeleeWeapon::GetRect();
		}
		break;
	case 1:
		{
			rect = MeleeWeapon::GetRect();
		}
		break;
	case 2:
		{
			rect = MeleeWeapon::GetRect();
			if(isAttacking)
				rect.bottom += 10;
		}
		break;
	case 3:
		{
			rect = MeleeWeapon::GetRect();
		}
		break;
	default:
		{
		}
		break;
	}

	return rect;
}